using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;

namespace TicTacToe
{
    public class GameSaver
    {
        public static readonly string KEY_NUM_TO_WIN = "NUM_TO_WIN";
        public static readonly string KEY_WINNABLE = "WINNABLE";
        public static readonly string KEY_CURRENT_PLAYER = "CURRENT_PLAYER";
        public static readonly string KEY_BOARD_SIZE = "BOARD_SIZE";
        public static readonly string KEY_WINNER = "WINNER";

        private static readonly string GAME_SAVE_FILE_NAME = "GameSaved.xml";
        private static readonly string DATA_FILE_NAME = "Data.xml";

        private static TicTacToePlayer[,] grid = null;
        private static XmlDictionary<string, string> data = null;

        public static string Load(string key)
        {
            XmlDictionary<string, string> data = LoadData();
            return data[key];
        }

        public static TicTacToePlayer[,] LoadGrid()
        {
            if (GameSaver.grid != null)
            {
                return GameSaver.grid;
            }

            List<List<TicTacToePlayer>> gridTemp = null;
            TextReader reader = null;
            try
            {
                IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication();
                if (isoStorage.FileExists(GAME_SAVE_FILE_NAME))
                {
                    IsolatedStorageFileStream file = isoStorage.OpenFile(GAME_SAVE_FILE_NAME, FileMode.Open);
                    XmlSerializer xs = new XmlSerializer(typeof(List<List<TicTacToePlayer>>));

                    reader = new StreamReader(file);
                    gridTemp = (List<List<TicTacToePlayer>>)xs.Deserialize(reader);
                    reader.Close();

                    isoStorage.DeleteFile(GAME_SAVE_FILE_NAME);
                }
            }
            finally
            {
                if (reader != null)
                {
                    reader.Dispose();
                }
            }

            TicTacToePlayer[,] gridRes = null;
            int size = gridTemp[0].Count;
            if (gridTemp != null)
            {
                gridRes = new TicTacToePlayer[size, size];
                for (int i = 0; i < size; i++)
                {
                    for (int j = 0; j < size; j++)
                    {
                        gridRes[i, j] = gridTemp[i][j];
                    }
                }
            }

            return gridRes;
        }

        public static bool CanLoad()
        {
            IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication();
            return isoStorage.FileExists(GAME_SAVE_FILE_NAME);
        }

        public static void Save(TicTacToePlayer[,] grid, BoardSize boardSize, int numToWin, TicTacToePlayer current, bool winnable, TicTacToePlayer winner)
        {
            GameSaver.grid = (TicTacToePlayer[,])grid.Clone();
            XmlDictionary<string, string> data = new XmlDictionary<string, string>();
            data[KEY_CURRENT_PLAYER] = current.ToString();
            data[KEY_NUM_TO_WIN] = numToWin.ToString();
            data[KEY_WINNABLE] = winnable.ToString();
            data[KEY_BOARD_SIZE] = boardSize.ToString();
            data[KEY_WINNER] = winner.ToString();

            SaveGrid(grid);
            SaveData(data);
        }

        private static void SaveData(XmlDictionary<string, string> data)
        {
            GameSaver.data = data;
            TextWriter writer = null;
            try
            {
                IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication();
                IsolatedStorageFileStream file = isoStorage.OpenFile(DATA_FILE_NAME, FileMode.Create);
                XmlSerializer xs = new XmlSerializer(typeof(XmlDictionary<string, string>));
                writer = new StreamWriter(file);
                xs.Serialize(writer, data);
                writer.Close();
            }
            finally
            {
                if (writer != null)
                {
                    writer.Dispose();
                }
            }
        }

        private static void SaveGrid(TicTacToePlayer[,] grid)
        {
            TextWriter writer = null;
            List<List<TicTacToePlayer>> temp = new List<List<TicTacToePlayer>>();
            for (int i = 0; i < grid.GetLength(0); i++)
            {
                List<TicTacToePlayer> t = new List<TicTacToePlayer>();
                for (int j = 0; j < grid.GetLength(0); j++)
                {
                    t.Add(grid[i, j]);
                }
                temp.Add(t);
            }

            try
            {
                IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication();
                IsolatedStorageFileStream file = isoStorage.OpenFile(GAME_SAVE_FILE_NAME, FileMode.Create);
                XmlSerializer xs = new XmlSerializer(typeof(List<List<TicTacToePlayer>>));
                writer = new StreamWriter(file);
                xs.Serialize(writer, temp);
                writer.Close();
            }
            finally
            {
                if (writer != null)
                {
                    writer.Dispose();
                }
            }
        }

        private static XmlDictionary<string, string> LoadData()
        {
            if (GameSaver.data != null)
            {
                return GameSaver.data;
            }

            XmlDictionary<string, string> data = null;
            TextReader reader = null;
            try
            {
                IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication();
                if (isoStorage.FileExists(DATA_FILE_NAME))
                {
                    IsolatedStorageFileStream file = isoStorage.OpenFile(DATA_FILE_NAME, FileMode.Open);
                    XmlSerializer xs = new XmlSerializer(typeof(XmlDictionary<string, string>));

                    reader = new StreamReader(file);
                    data = (XmlDictionary<string, string>)xs.Deserialize(reader);
                    reader.Close();

                    isoStorage.DeleteFile(DATA_FILE_NAME);
                }
            }
            finally
            {
                if (reader != null)
                {
                    reader.Dispose();
                }
            }

            GameSaver.data = data;
            return data;
        }
    }
}
